/*
 * @Date: 2019-06-01 19:05:26
 * @Author: Ryan Huang
 * @Description:
 */
package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"my/homework/chatroom1/constants"
	"my/homework/chatroom1/libs"
	"my/homework/chatroom1/variables"
	"net"
	"os"
	"time"
)

func main() {
	defer libs.CatchErr()
	tcpAddr, _ := net.ResolveTCPAddr(constants.TCP, constants.ServerAddr)
	conn, errDial := net.DialTCP(constants.TCP, nil, tcpAddr)
	defer conn.Close()
	if errDial != nil {
		fmt.Println(errDial)
	}
	reader := bufio.NewReader(os.Stdin)
	askNamePass(reader, conn)
	go func() {
		for {
			err := getOtherMsg(conn)
			if err == io.EOF {
				fmt.Println("服务器异常")
				os.Exit(0)
			}
		}
	}()
	index := 0
	//接下来给server发消息
	for {
		index++
		line := libs.ReadLine(reader)
		if len(line) > constants.MessageMaxLen {
			fmt.Println(constants.MessageTooLong)
			continue
		}
		header := variables.Header{index, time.Now().Unix()}
		content := variables.Body{line}
		msg := variables.Msg{header, content}
		_, err := conn.Write(libs.ToJson(msg))
		if err != nil {
			panic(err)
		}
	}
}

func askNamePass(reader *bufio.Reader, conn *net.TCPConn) string {
	fmt.Println("请输入你的用户名")
	name := libs.ReadLine(reader)
	fmt.Println("请输入你的密码")
	password := libs.ReadLine(reader)
	localAddr := conn.LocalAddr().String()
	header := variables.Header{0, time.Now().Unix()}
	identity := variables.Identity{header, localAddr, name, password}
	_, err := conn.Write(libs.ToJson(identity))
	if err != nil {
		panic(err)
	}
	/*
		buf := make([]byte, constants.MessageMaxLen)
		n, _ := conn.Read(buf)
		var response map[string]interface{}
		json.Unmarshal(buf[:n], &response)
	*/
	response, err1 := getResponse(conn)
	if err1 != nil {
		os.Exit(0)
	}
	flag := response["flag"]
	if flag == true {
		fmt.Println("进入聊天室...................")
		fmt.Println("------------------------------")
	} else {
		fmt.Println(response["msg"])
		fmt.Println("------------------------------")
		askNamePass(reader, conn)
	}
	return name
}

func getResponse(conn net.Conn) (map[string]interface{}, error) {
	var response map[string]interface{}
	buf := make([]byte, constants.MessageMaxLen)
	n, err := conn.Read(buf)
	if err != nil {
		return response, err
	}
	json.Unmarshal(buf[:n], &response)
	return response, nil
}

func getOtherMsg(conn net.Conn) error {
	response, err := getResponse(conn)
	if err != nil {
		return err
	}
	fmt.Println(fmt.Sprintf("%s", response["msg"]))
	return nil
}
